package com.clh.controller;

import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;

import com.clh.common.PageInfo;
import com.clh.dto.Result;
import com.clh.entity.Admin;
import com.clh.entity.Owner;
import com.clh.service.OwnerService;
import com.clh.service.impl.OwnerServiceImpl;
import com.clh.util.RegexUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * Servlet implementation class OwnerServlet
 */
/**
 * 
 * @Description: TODO
 * @author 张经伟
 * @date 2022年5月27日 下午4:54:36
 * @version v1.0
 */
@WebServlet("/OwnerServlet")
@MultipartConfig
public class OwnerServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	private OwnerService ownerService = new OwnerServiceImpl();
	private Owner owner = new Owner();

	/**
	 * @see HttpServlet#service(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String op = request.getParameter("op");
		if ("page".equals(op)) {
			this.doQueryByPage(request, response);
		} else if ("delete".equals(op)) {
			this.doDeleteById(request, response);
		} else if ("login".equals(op)) {
			this.doLogin(request, response);
		} else if ("LoginOut".equals(op)) {
			this.doLoginOut(request, response);
		} else if("add".equals(op)){
			this.doAddOwner(request,response);
		} else if("findById".equals(op)) {
			this.doFindById(request,response);
		} else if("findByPhone".equals(op)){
			this.doFindByPhone(request,response);
		} else if("update".equals(op)){
			try {
				this.doUpdate(request,response);
			} catch (IOException | ServletException | ParseException e) {
				
				e.printStackTrace();
			}
		}
		
	}

	/**
	 * @param request
	 * @param response
	 * @throws IOException 
	 */
	private void doFindByPhone(HttpServletRequest request, HttpServletResponse response) throws IOException {
		Result result = new Result();
		String ownerPhoneNumber = request.getParameter("ownerPhoneNumber");
		
		if(ownerPhoneNumber == null || "".equals(ownerPhoneNumber)) {
			result.fail(0, "参数错误");
		}else {
			//调用业务层
			List<Owner> owner = ownerService.getOwnerByPhone(ownerPhoneNumber);
			
			if(owner != null) {
				result.ok(owner);
			}else {
				result.fail(0, "没有相关的数据");
			}
		}
		// 设置响应的内容格式
		response.setContentType("application/json;charset=utf-8");
		// 利用第三方的JASON转换
		ObjectMapper objectMapper = new ObjectMapper();
		String json = objectMapper.writeValueAsString(result);
		// 创建响应并将数据返回给浏览器
		response.getWriter().write(json);
		
	}

	/**
	 * @param request
	 * @param response
	 * @throws IOException 
	 */
	private void doFindById(HttpServletRequest request, HttpServletResponse response) throws IOException {
		//返回统一的结果对象
				Result result =new Result();
				//接收请求参数
				String roomNo = request.getParameter("roomNo");
				//校验参数
				if(roomNo == null || "".equals(roomNo)) {
					result.fail(0, "参数错误");
				}else {
					//调用业务层
					Owner owner = ownerService.getOwnerById(roomNo);
					if(owner != null) {
						result.ok(owner);
					}else {
						result.fail(0, "没有相关数据");
					}
				}
				
				//响应
				// 设值响应的内容类型
				response.setContentType("application/json;charset=utf-8");
				// 利用第三方库进行Jackson的转换
				ObjectMapper objectMapper = new ObjectMapper();
				String json = objectMapper.writeValueAsString(result);
				// 创建响应并将数据返回给浏览器
				response.getWriter().write(json);
		
	}

	/**
	 * @param request
	 * @param response
	 * @throws ServletException 
	 * @throws IOException 
	 * @throws ParseException 
	 */
	private void doUpdate(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, ParseException {
		//返回统一的结果对象
		Result result =new Result();
		
		
		//接收请求参数
		String roomNo = request.getParameter("roomNo");
		String ownerName = request.getParameter("ownerName");
		String ownerId = request.getParameter("ownerId");
		String ownerPhoneNum = request.getParameter("ownerPhoneNumber");
		String checkInTime = request.getParameter("checkInTime");
		String ownerImage = request.getParameter("ownerImage");
		String ownerPassword = request.getParameter("ownerPassword");
		String roomArea = request.getParameter("ownerArea");
		
		//文件
		Part part = request.getPart("ownerImage");
		// 源文件名
		String imageFileName = request.getParameter("imageFileName");
		
		//校验
		if(ownerId != null && RegexUtil.validateOwnerId(ownerId)
				 && ownerPhoneNum != null && RegexUtil.validatePhoneNumber(ownerPhoneNum)) {
			Owner owner = new Owner();
			owner.setRoomNo(roomNo);
			owner.setOwnerName(ownerName);
			owner.setOwnerId(ownerId);
			owner.setOwnerPhoneNumber(ownerPhoneNum);
			//时间处理
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			Date checktime = df.parse(checkInTime);
			owner.setCheckInTime(checktime);
			owner.setOwnerImage(ownerImage);
			owner.setOwnerPassword(ownerPassword);
			owner.setRoomArea(new BigDecimal(roomArea));
			
			//定义文件上传是否出错
			boolean errorFlag = false;
			//判断是否包含文件
			if(part.getSize() > 0) {
				//对文件进行处理，处理文件类型，文件大小，文件名唯一化，储存到文件的指定位置，设置商品对象的图片属性为文件名，数据库存储的图片字段文件名
				//设置统一的响应格式
				//获取文件内容类型
				String contentType = part.getContentType();
				//设置支持文件内容的类型
				String allowContentType = "image/jpeg;image/png;image/gif";
				//校验文件类型是否合法
				if(allowContentType.indexOf(contentType) == -1) {
					//设置响应对象
					result.fail(0, "文件类型不合法，只允许图片类型：image/jpeg;image/png;image/gif");
				}else if(part.getSize() > 10240000){  //校验文件大小是否合法
					//设置响应对象
					result.fail(0, "文件大小不合法，最大只能支持10000KB");
				}else  {
					//获取源文件名
					String fileName = part.getSubmittedFileName();//iphone13.jpg
					
					//保证储存的文件名是唯一的
					//这时可以采用唯一序列UUID，采用时间戳+随机数
					UUID uuid = UUID.randomUUID();
					
					StringBuffer storeFileName = new StringBuffer();
					
					//情况1 保留源文件名
					//storeFileName.append(uuid).append(fileName);
					
					//情况2 不保留源文件名
					storeFileName.append(uuid).append(fileName.substring(fileName.lastIndexOf(".")));
					
					//储存文件
					//file类关联储存文件的目录
					File file = new File("E:\\upload\\image");
					
					//定义完整的文件路径
					StringBuffer filePath = new StringBuffer();
					filePath.append(file).append(File.separator).append(storeFileName);//D;\\upload\\image\\
					//将上传的文件存储到指定的服务器
					part.write(filePath.toString());
					
					//设置响应对象
					result.ok(true).setMessage("提交成功，并储存文件!");
					//对商品对象的图片属性设值
					owner.setOwnerImage(storeFileName.toString());
					
					//判断该商品是否有存在原图片
					if(imageFileName != null && !"".endsWith(imageFileName)) {
						//将原来的图片文件删除
						File oldfile = new File("E:\\upload\\image\\" + imageFileName);
						oldfile.delete();
					}
				}
			}else {
				//更新时候没有上传新的图片
				//判断该业主有没有存在图片，有则对对象的图片属性和设值-原来的文件名
				if(imageFileName != null && !"".endsWith(imageFileName)) {
					owner.setOwnerImage(null);
				}
			}
				
			
			//当文件上传没有出错的时候才可以调用业务层
			if(!errorFlag) {
				//调用业务层
				boolean f = ownerService.modifyOwner(owner);
				if(f) {
					result.ok(f);
				} else {
					result.fail(0, "信息修改失败");
				}
			}
			
		}else {
			result.fail(0, "身份证或手机号不合法");	
		}
		
		
		
		//响应
		// 设值响应的内容类型
			response.setContentType("application/json;charset=utf-8");
			// 利用第三方库进行Jackson的转换
			ObjectMapper objectMapper = new ObjectMapper();
			String json = objectMapper.writeValueAsString(result);
			// 创建响应并将数据返回给浏览器
			response.getWriter().write(json);
		
	}

	/**
	 * @param request
	 * @param response
	 * @throws ServletException 
	 * @throws IOException 
	 * @throws ParseException 
	 */
	private void doAddOwner(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException  {
		Result result =new Result();
		
		
			String roomNo = request.getParameter("roomNo");
			String ownerName = request.getParameter("ownerName");
			String ownerId = request.getParameter("ownerId");
			String ownerPhoneNum = request.getParameter("ownerPhoneNumber");
			String checkInTime = request.getParameter("checkInTime");
			String ownerImage = request.getParameter("ownerImage");
			String ownerPassword = request.getParameter("ownerPassword");
			String roomArea = request.getParameter("ownerArea");
			Part part = request.getPart("ownerImage");
			String imageFileName = request.getParameter("imageFileName");
			
			
			Owner owner = new Owner();
			owner.setRoomNo(roomNo);
			owner.setOwnerName(ownerName);
			owner.setOwnerId(ownerId);
			owner.setOwnerPhoneNumber(ownerPhoneNum);
			//时间处理
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			Date checktime;
			try {
				checktime = df.parse(checkInTime);
				owner.setCheckInTime(checktime);
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			owner.setOwnerImage(ownerImage);
			owner.setOwnerPassword(ownerPassword);
			owner.setRoomArea(new BigDecimal(roomArea));
			
			if(ownerId != null && RegexUtil.validateOwnerId(ownerId)
					 && ownerPhoneNum != null && RegexUtil.validatePhoneNumber(ownerPhoneNum)) {
				
				if(ownerService.addOwner(owner)) {
					result.ok(true).setMessage("添加成功");
				}else {
					result.fail(0, "格式错误");
				}			
			}
			
			boolean errorFlag = false;
			//判断是否包含文件
			if(part.getSize() > 0) {
				//对文件进行处理，处理文件类型，文件大小，文件名唯一化，储存到文件的指定位置，设置商品对象的图片属性为文件名，数据库存储的图片字段文件名
				//设置统一的响应格式
				//获取文件内容类型
				String contentType = part.getContentType();
				//设置支持文件内容的类型
				String allowContentType = "image/jpeg;image/png;image/gif";
				//校验文件类型是否合法
				if(allowContentType.indexOf(contentType) == -1) {
					//设置响应对象
					result.fail(0, "文件类型不合法，只允许图片类型：image/jpeg;image/png;image/gif");
				}else if(part.getSize() > 10240000){  //校验文件大小是否合法
					//设置响应对象
					result.fail(0, "文件大小不合法，最大只能支持10000KB");
				}else  {
					//获取源文件名
					String fileName = part.getSubmittedFileName();
					
					//保证储存的文件名是唯一的
					//这时可以采用唯一序列UUID，采用时间戳+随机数
					UUID uuid = UUID.randomUUID();
					
					StringBuffer storeFileName = new StringBuffer();
					
					//情况1 保留源文件名
					//storeFileName.append(uuid).append(fileName);
					
					//情况2 不保留源文件名
					storeFileName.append(uuid).append(fileName.substring(fileName.lastIndexOf(".")));
					
					//储存文件
					//file类关联储存文件的目录
					File file = new File("E:\\upload\\image");
					
					//定义完整的文件路径
					StringBuffer filePath = new StringBuffer();
					filePath.append(file).append(File.separator).append(storeFileName);//D;\\upload\\image\\
					//将上传的文件存储到指定的服务器
					part.write(filePath.toString());
					
					//设置响应对象
					result.ok(true).setMessage("提交成功，并储存文件!");
					//图片属性具体区分
					owner.setOwnerImage(storeFileName.toString());
				}
			}
			
			//当文件上传没有出错的时候才可以调用业务层
			if(!errorFlag) {
				//调用业务层
				boolean f = ownerService.addOwner(owner);
				if(f) {
					result.ok(f);
				} else {
					result.fail(0, "业主信息添加失败");
				}
			}
			
			//响应
			// 设值响应的内容类型
				response.setContentType("application/json;charset=utf-8");
				// 利用第三方库进行Jackson的转换
				ObjectMapper objectMapper = new ObjectMapper();
				String json = objectMapper.writeValueAsString(result);
				// 创建响应并将数据返回给浏览器
				response.getWriter().write(json);
		
	}

	/**
	 * @param request
	 * @param response
	 * @throws IOException 
	 */
	private void doLoginOut(HttpServletRequest request, HttpServletResponse response) throws IOException {
		// 删除session中用户登录信息
		HttpSession session = request.getSession();
		session.removeAttribute("ownerSession");
		// 重定向要登录页面
		response.sendRedirect(request.getContextPath() + "/front/login.jsp");
	}

	/**
	 * @param request
	 * @param response
	 */
	private void doLogin(HttpServletRequest request, HttpServletResponse response) {
		// 管理登录接口处理
		// 1、对登录参数（手机号码和密码）进行校验，当格式错误重定向到登录页并提示“格式错误”
		// 2、当参数格式正确，账号不存在重定向到登录页并提示“登录失败，手机号或密码错误”
		// 3、账号存在，将会话登录用户对象存储到session中；当用户选择“记住密码”，将用户登录信息存入cookie中相应给客户端保存，最后重定向到“后台首页”
		// 设置相应的内容类型
		response.setContentType("text/html;charset=utf-8");
		try {
			// 获取登录请求的传递参数 房号，密码，记住密码标识
			String phoneNumber = request.getParameter("phoneNumber");
			String password = request.getParameter("password");
			String remember = request.getParameter("remember");
			System.out.println("+++++++++phoneNumber" + phoneNumber);
			System.out.println("+++++++++password" + password);
			System.out.println("+++++++++remember" + remember);
			// 对手机号和密码进行校验
			if (phoneNumber != null && password != null && RegexUtil.validatePassword(password)
					&& RegexUtil.validatePhoneNumber(phoneNumber)) {
				// 1、手机号码不为空，密码不为空 手机号码和密码符合格式要求
				// 调用业务层
				Owner owner = ownerService.login(phoneNumber, password);
				// 判断账号是否存在
				if (owner != null) {
					// 2、账号存在
					// 将当前会话的用户存储到session中
					HttpSession session = request.getSession();
					session.setAttribute("ownerSession", owner);
					if ("remember".equals(remember) && remember != null) {// 选中记住密码
						// 记住密码，在相应头中添加cookie保存用户信息，并设置有效期2天，name设置“rememberMe” value设置"登录手机号=密码“
						// 创建cookie对象
						Cookie cookie = new Cookie("rememberMe", phoneNumber + "=" + password);
						// 设置有效期2天
						cookie.setMaxAge(60 * 60 * 24 * 2);
						// 添加到相应中
						response.addCookie(cookie);
					} else {// 没选中记住密码
							// 取消记住密码，删除对应的cookie
						Cookie cookies[] = request.getCookies();// 得到cookie的数组
						for (Cookie cookie : cookies) {
							// 获取当前用户的cookie
							if ("rememberMe".equals(cookie.getName())) {
								// 设置时间长度为0，即删除
								cookie.setMaxAge(0);
								// 添加到响应头
								response.addCookie(cookie);
							}
						}
					}
					// 前往首页
					response.sendRedirect(request.getContextPath() + "/front/index.jsp");
				} else {
					// 2、账号不存在，账号密码错误，前往登录页
					String message = "登录失败，手机号或密码错误,不存在该账号";
					message = URLEncoder.encode(message, "UTF-8");
					response.sendRedirect(request.getContextPath() + "/front/login.jsp?message=" + message);
				}
			} else {
				// 1、格式问题
				String message = "登录失败，手机号或密码格式错误";
				message = URLEncoder.encode(message, "UTF-8");
				response.sendRedirect(request.getContextPath() + "/front/login.jsp?message=" + message);
			}
		} catch (Exception e) {
			// TODO: handle exception
		}

	}

	/**
	 * @param request
	 * @param response
	 */
	private void doDeleteById(HttpServletRequest request, HttpServletResponse response) {
		Result result = new Result();
		try {
			String roomNo = request.getParameter("roomNo");
			if (roomNo == null || "".equals(roomNo)) {
				result.fail(400, "参数错误");
			} else {
				int n = ownerService.deleteById(roomNo);
				if (n > 0) {
					result.ok(true).setMessage("删除成功");
				} else {
					result.fail(0, "删除失败，可能不存在");
				}
			}
			response.setContentType("application/json;charset=utf-8");
			ObjectMapper objectMapper = new ObjectMapper();
			String json = objectMapper.writeValueAsString(result);
			response.getWriter().write(json);
		} catch (Exception e) {
			result.fail(500, "服务器出错");
			e.printStackTrace();
		}

	}

	/**
	 * @param request
	 * @param response
	 * @throws IOException
	 */
	private void doQueryByPage(HttpServletRequest request, HttpServletResponse response) throws IOException {
		Result result = new Result();

		String ownerName = request.getParameter("ownerName");
		String roomNo = request.getParameter("roomNo");
		String pageNum = request.getParameter("pageNum");
		String pageSize = request.getParameter("pageSize");

		if ((pageNum == null || "".equals(pageNum) || Integer.parseInt(pageNum) < 0)
				|| (pageNum == null  || Integer.parseInt(pageNum) < 0)
				|| (pageSize == null || "".equals(pageSize) || Integer.parseInt(pageSize) < 0)) {
			result.fail(0, "参数错误");
		} else {
			Owner owner = new Owner();
			owner.setOwnerName(ownerName);
			owner.setRoomNo(roomNo);
			PageInfo pageInfo = ownerService.getOwnerListByPage(owner, Integer.parseInt(pageNum),
					Integer.parseInt(pageSize));
			if (!pageInfo.getList().isEmpty()) {
				result.ok(pageInfo);
			} else {
				result.fail(0, "没有相关数据");
			}
		}

		response.setContentType("application/json;charset=utf-8");
		ObjectMapper objectMapper = new ObjectMapper();
		String json = objectMapper.writeValueAsString(result);
		response.getWriter().write(json);
	}

}
